<?php
namespace Kuoqi\Api\Weixin\Pay;
use Kuoqi\Api\Weixin\Mp\Response;
use Kuoqi\Error;
use Kuoqi\Api\Weixin\Tools;
use Kuoqi\Api\Weixin\Config;

/**
 * 预支付的订单下单
 * Class Prepay
 * @package Kuoqi\Api\Weixin\Mp
 */
class Prepay{

    public $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';//接口请求地址

    //public $appid = '';//关联的appid的值
    public $body = '';//产品名称,预留展示内容信息
    public $fee_type = 'CNY';//money 类型
    public $openid = '';//交易时候的openid
    //public $mch_id = '';//商户ID
    public $nonce_str = '';//随机字符串
    public $notify_url = '';//返回地址
    public $out_trade_no = '';//订单号
    public $sign = '';//sign签名校验
    public $spbill_create_ip = '';//商户ip,$_SERVER['REMOTE_ADDR'];
    public $total_fee = '';//总价格
    /**
     * @var string 签名类型[JSAPI:APP:TWO:MWEB]
     * JSAPI : jsapi类型
     * APP : app类型
     * NATIVE : 二维码类型
     * MWEB : H5类型
     */
    public $trade_type = '';//签名类型[JSAPI:APP:NATIVE:MWEB]
    public $_config = array();//配置的信息
    protected $_xml = '';//获取的xml文件信息

    public $is_valied = 1;//是否验证成功
    public $errmsg = '';//异常的相关信息
    public function isValied(){ return $this->is_valied;}
    public function getError(){ return $this->errmsg;}

    /**
     * Prepay constructor. 初始化
     */
    public function __construct()
    {
        $this->spbill_create_ip = $_SERVER['REMOTE_ADDR'];
        $this->out_trade_no = date('YMd',time()).rand(100000,999999);
        $this->nonce_str = md5(date('YMd',time()).rand(100000,999999));
    }

    /**
     * createby kuoqi at 2022/10/22 12:07 已微信里面的模式进行数据获取
     */
    public function flushWithjsapi(){
        $this->_config = array(
            'appid'=>Config::$mp_appid,
            'body'=>'VIP充值',//产品名称
            'fee_type'=>'CNY',//money 类型
            'mch_id'=>Config::$mch_id,
            'nonce_str'=>$this->nonce_str,
            'notify_url'=>$this->notify_url,//返回地址
            'openid'=>$this->openid,//openid
            'out_trade_no'=>$this->out_trade_no,//订单号
            //'sign'=>md5('key'),//sign签名校验
            'spbill_create_ip'=>isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'127.0.0.1',//商户ip
            'total_fee'=>intval($this->total_fee),//总价格
            'trade_type'=>'JSAPI',//签名类型
        );
    }

    /**
     * createby kuoqi at 2022/10/22 12:10 app的方式获取配置
     */
    public function flushWithapp(){
        $this->_config = array(
            'appid'=>Config::$mp_appid,
            'body'=>'VIP充值',//产品名称
            'fee_type'=>'CNY',//money 类型
            'mch_id'=>Config::$mch_id,
            'nonce_str'=>md5(date('YMd',time()).rand(100000,999999)),
            'notify_url'=>$this->notify_url,//返回地址
            'out_trade_no'=>date('Ymd',time()).rand(100000,999999),//订单号
            //'sign'=>md5('key'),//sign签名校验
            'total_fee'=>intval($this->total_fee),//总价格
            'trade_type'=>'APP',//签名类型
        );
    }

    /**
     * createby kuoqi at 2022/10/22 12:11 获取二维码的配置信息
     */
    public function flushWithnative(){
        $this->_config = array(
            'appid'=>Config::$mp_appid,
            'body'=>'VIP充值',//产品名称
            'fee_type'=>'CNY',//money 类型
            'mch_id'=>Config::$mch_id,
            'nonce_str'=>md5(date('YMd',time()).rand(100000,999999)),
            'notify_url'=>$this->notify_url,//返回地址
            'out_trade_no'=>date('Ymd',time()).rand(100000,999999),//订单号
            //'sign'=>md5('key'),//sign签名校验
            'spbill_create_ip'=>isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'127.0.0.1',
            'total_fee'=>intval($this->total_fee),//总价格
            'trade_type'=>'NATIVE',//签名类型
        );
    }

    /**
     * createby kuoqi at 2022/10/22 12:12 获取h5的配置信息
     */
    public function flushWithmweb(){
        $this->_config = array(
            'appid'=>Config::$mp_appid,
            'body'=>'VIP充值',//产品名称
            'fee_type'=>'CNY',//money 类型
            'mch_id'=>Config::$mch_id,
            'nonce_str'=>md5(date('YMd',time()).rand(100000,999999)),
            'notify_url'=>$this->notify_url,//返回地址
            'out_trade_no'=>date('Ymd',time()).rand(100000,999999),//订单号
            //'sign'=>md5('key'),//sign签名校验
            'spbill_create_ip'=>isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'127.0.0.1',
            'total_fee'=>intval($this->total_fee),//总价格
            'trade_type'=>'MWEB',//签名类型
        );
    }

    protected function createXml(){
        $this->_xml='<xml>';
        !isset($this->_config['appid']) || $this->_xml.='<appid>'.$this->_config['appid'].'</appid>';
        !isset($this->_config['body']) || $this->_xml.='<body>'.$this->_config['body'].'</body>';
        !isset($this->_config['fee_type']) || $this->_xml.='<fee_type>'.$this->_config['fee_type'].'</fee_type>';
        !isset($this->_config['mch_id']) || $this->_xml.='<mch_id>'.$this->_config['mch_id'].'</mch_id>';
        !isset($this->_config['nonce_str']) || $this->_xml.='<nonce_str>'.$this->_config['nonce_str'].'</nonce_str>';
        !isset($this->_config['notify_url']) || $this->_xml.='<notify_url>'.$this->_config['notify_url'].'</notify_url>';
        !isset($this->_config['openid']) || $this->_xml.='<openid>'.$this->_config['openid'].'</openid>';
        !isset($this->_config['out_trade_no']) || $this->_xml.='<out_trade_no>'.$this->_config['out_trade_no'].'</out_trade_no>';
        !isset($this->_config['spbill_create_ip']) || $this->_xml.='<spbill_create_ip>'.$this->_config['spbill_create_ip'].'</spbill_create_ip>';
        !isset($this->_config['total_fee']) || $this->_xml.='<total_fee>'.$this->_config['total_fee'].'</total_fee>';
        !isset($this->_config['trade_type']) || $this->_xml.='<trade_type>'.$this->_config['trade_type'].'</trade_type>';
        !isset($this->_config['sign']) || $this->_xml.='<sign>'.$this->_config['sign'].'</sign>';
        $this->_xml.='</xml>';
    }

    /**
     * 发送数据包
     * createby kuoqi at 2022/10/22 13:07
     */
    protected function send(){
        return Tools::xmlToArray(Tools::sendTo($this->url,'XML',$this->_xml,'string'));
    }

    /**
     * 冲刷一个完整的配置
     * createby kuoqi at 2022/10/22 11:52
     */
    public function flush(){
        $this->trade_type = strtoupper($this->trade_type);
        switch($this->trade_type){
            case 'JSAPI':$this->flushWithjsapi();break;
            case 'APP':$this->flushWithapp();break;
            case 'NATIVE':$this->flushWithnative();break;
            case 'MWEB':$this->flushWithmweb();break;
            default:throw new Error("暂不支持该种支付类型");
        }
        $this->_config['sign'] = Tools::signMd5($this->_config,Config::$mch_key);
        $this->createXml();//创建xml文件
        $data = $this->send();//数据验签之后发送数据包
        return $data;
    }
    /**
     * createby kuoqi at 2022/10/23 19:59 预支付的接口信息，会自动返回相关配置信息
     * @return array|int
     * @throws Error
     * 网页端接口请求参数列表（参数需要重新进行签名计算，参与签名的参数为：appId、timeStamp、nonceStr、package、signType，参数区分大小写。）
     */
    public function prepay(){
        $res = $this->flush();
        if($res['return_code']=='FAIL'){
            $this->is_valied = 0;
            $this->errmsg = '通讯失败：'.$res['return_msg'];
            return $this->is_valied;
        }
        if($res['result_code']=='FAIL'){
            $this->is_valied = 0;
            $this->errmsg = '交易失败：'.$res['err_code_des'];
            return $this->is_valied;
        }
        $config = array(
            'appId'=>Config::$mp_appid,
            'timeStamp'=>time(),
            'nonceStr'=>time().rand(10,99),
            'package'=>sprintf('prepay_id=%s',$res['prepay_id']),
            'signType'=>'MD5',
        );
        $config['paySign'] = Tools::signMd5($config,Config::$mch_key);
        //$config['paySign'] = Tools::signMd5($config,$res['sign']);
        return $config;
    }
}